package edu.uoc.tdp.servidor.bbdd.proves;


import edu.uoc.tdp.beans.proves.Prova;
import edu.uoc.tdp.beans.proves.EstatProva;
import edu.uoc.tdp.common.EOlympicsException;
import edu.uoc.tdp.common.EOlympicsExceptionProva;
import edu.uoc.tdp.bbdd.GestorDiscConnexio;
import edu.uoc.tdp.beans.conexio.Estudiant;
import edu.uoc.tdp.beans.estudiants.Participacio;
import edu.uoc.tdp.beans.proves.RondaEliminatoria;
import edu.uoc.tdp.beans.proves.RondaFinal;
import edu.uoc.tdp.common.EOlympicsUtils;
import java.sql.Connection;
import java.util.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;




/**
 * Classe Gestora de proves
 * TDP Grup 1X4J
 */


public class GestorProva {
    
    private GestorDiscConnexio gestor;
    private Connection connexio;

    /**
     * Constructor de la classe Gestora
     * Crea un nou gestor de disc.
     */
    public GestorProva() throws EOlympicsException {
        this.gestor = new GestorDiscConnexio();
        this.gestor.obreConnexioBD();
        this.connexio = gestor.getConnexio();
    }

    /**
     * Constructor de la classe Gestora
     * Utilitza el gestor de disc passat com a paràmetre
     * @param gdc connexió a la BD de tipus GestorDiscConnexio
     */
    public GestorProva(GestorDiscConnexio gdc) {
        this.gestor   = gdc;
        this.connexio = gdc.getConnexio();
    }
    
     /**
     * Obté les proves que es poden tancar
     * @return  llistat de proves
     * @throws EOlympicsException
     * @throws EOlympicsExceptionProva 
     */
    public List<Prova> getProvesPerTancar() throws EOlympicsException, EOlympicsExceptionProva{
        Date avui= new Date(System.currentTimeMillis());
        List <Prova>proves= new ArrayList<Prova>();        
        Prova prova;
        String sql="SELECT DISTINCT P.idProva,P.descripcio,P.dataIniInscripcio,P.dataFiInscripcio,P.nombrePlaces, P.estat, "
                + "(Select Count(1) FROM inscripcio I WHERE I.idProva =P.idProva) as inscripcions,R.tipusRonda, R.dataIniciRealitzacio, R.dataFiRealitzacio "               
                + "FROM PROVA P, RONDA R  "                
                + "WHERE P.idProva=R.idProva "
                + "AND ((P.estat='"+ EstatProva.COMPETICIOPREVIA.getEstat() +"' AND R.dataFiRealitzacio+1<='" + avui +"' AND R.tipusRonda='E') " 
                + "OR (P.estat='"+ EstatProva.COMPETICIOFINAL.getEstat() +"' AND R.dataFiRealitzacio+1<='" + avui +"' AND R.tipusRonda='F'))"; 
     
        
        Statement st=gestor.creaSentencia();
        try{
            ResultSet rs=st.executeQuery(sql);
            while (rs.next()){                                                
                prova=new Prova(rs.getInt(1),rs.getString(2),rs.getDate(3),rs.getDate(4),rs.getInt(5));
                prova.setEstat(EstatProva.valueOf(rs.getString(6)));
                prova.setNombreInscrits(rs.getInt(7));
                if(rs.getString(8).equals("E")){
                    RondaEliminatoria ronda=new RondaEliminatoria();
                    ronda.setDataIniRealitzacio(rs.getDate(9));
                    ronda.setDataFiRealitzacio(rs.getDate(10));
                    prova.setRondaEliminatoria(ronda);
                }
                else
                {
                    RondaFinal ronda =new RondaFinal();
                    ronda.setDataIniRealitzacio(rs.getDate(9));
                    ronda.setDataFiRealitzacio(rs.getDate(10));
                    prova.setRondaFinal(ronda);
                }
                
                proves.add(prova);                
            }
            st.close();
            rs.close();
        }catch (SQLException sqle){
            treatExceptionSQL(sqle.getMessage());
            
        }catch (Exception e){
            System.out.println(e.getMessage());
            throw new EOlympicsException(EOlympicsException.ERR_DESC_EXEC);
        }                       
        
        return proves;
    }
    /**
     * 
     * Obté les proves en estat de tancar les inscripcions
     * @return  Llistat de proves
     * @throws EOlympicsException
     * @throws EOlympicsExceptionProva 
     */
    public List<Prova> getProvesInscripcions()throws EOlympicsException, EOlympicsExceptionProva{
       java.sql.Date avui= new java.sql.Date(System.currentTimeMillis());        
       
        List <Prova>proves= new ArrayList<Prova>();        
        Prova prova;
        String sql="SELECT  P.idProva,P.descripcio,P.dataIniInscripcio,P.dataFiInscripcio,P.nombrePlaces,"
                + "P.estat,(select count(*) From inscripcio I where P.idProva=I.idProva) as inscrits,"
                + "R.tipusRonda,R.datainicirealitzacio,R.datafirealitzacio,R.nombrePreguntes "
                + "FROM PROVA P, RONDA R  "                
                + "WHERE P.idProva=R.idProva "
                + "AND ((P.estat='"+ EstatProva.INICIAL.getEstat() +"' AND P.dataFiInscripcio+1<='" + avui +"' "
                + "AND R.tipusronda='E') "
                + "OR (P.estat='"+ EstatProva.INICIAL.getEstat() + "' AND P.dataFiInscripcio+1<='"+avui+"' " 
                + "AND R.tipusronda='F' AND (SELECT count (*) FROM RONDA WHERE idProva= p.idProva and tipusRonda='E')=0)) " ;
        
        Statement st=gestor.creaSentencia();
        try{
            ResultSet rs=st.executeQuery(sql);
            while (rs.next()){                                                
                prova=new Prova(rs.getInt(1),rs.getString(2),rs.getDate(3),rs.getDate(4),rs.getInt(5));
                prova.setEstat(EstatProva.valueOf(rs.getString(6)));
                prova.setNombreInscrits(rs.getInt(7));
                if(rs.getString(8).equals("E")){
                    RondaEliminatoria ronda=new RondaEliminatoria();
                    ronda.setDataIniRealitzacio(rs.getDate(9));
                    ronda.setDataFiRealitzacio(rs.getDate(10));
                    prova.setRondaEliminatoria(ronda);
                }
                else
                {
                    RondaFinal ronda =new RondaFinal();
                    ronda.setDataIniRealitzacio(rs.getDate(9));
                    ronda.setDataFiRealitzacio(rs.getDate(10));
                    prova.setRondaFinal(ronda);
                }                
                if(prova.getEstat().equals(EstatProva.INICIAL.getEstat())){
                    prova.setEstat(EstatProva.INSCRIPCIO);
                }
                proves.add(prova);
                
            }
            st.close();
            rs.close();
        }catch (SQLException sqle){
            treatExceptionSQL(sqle.getMessage());
            
        }catch (Exception e){
            System.out.println(e.getMessage());
            throw new EOlympicsException(EOlympicsException.ERR_DESC_EXEC);
        }                       
        
        return proves;
    }
    /**
     * Accessor de lectura, recupera totes les proves en periode de realització Eliminatoria
     * @return Llista de proves
     * @throws EOlympicsException 
     */
    public List<Prova> getProvesEliminatories() throws EOlympicsException, EOlympicsExceptionProva{        
        java.sql.Date avui= new java.sql.Date(System.currentTimeMillis());        
        System.out.println("avui:"+ avui.getDay()+avui.getMonth());
        
        String sql="SELECT P.idProva,P.descripcio,P.dataIniInscripcio,P.dataFiInscripcio,P.nombrePlaces "
                + "FROM PROVA P,RONDA R "                
                + "WHERE P.idProva = R.idProva "
                + "AND R.tipusRonda = 'E' "
                + "AND R.dataIniciRealitzacio<='"+avui+"' "
                + "AND R.dataFiRealitzacio >='"+avui+"' "                
                + "AND P.estat<> '"  +EstatProva.TANCADA.getEstat() +"' "
                + "AND P.estat<>'"  +EstatProva.CANCELADA.getEstat() +"' ";
        
        return getProves(sql);
    }
    /**
     * Accessor de lectura, recupera totes les proves en periode de realització Final
     * @return Llista de proves
     * @throws EOlympicsException 
     */
    public List<Prova> getProvesFinals() throws EOlympicsException, EOlympicsExceptionProva{        
        Date avui= new Date(System.currentTimeMillis());        
        String sql="SELECT P.idProva,P.descripcio,P.dataIniInscripcio,P.dataFiInscripcio,P.nombrePlaces "
                + "FROM PROVA P,RONDA R "                
                + "WHERE P.idProva = R.idProva "
                + "AND R.tipusRonda = 'F' "
                + "AND R.dataIniciRealitzacio<='"+avui+"' "
                + "AND R.dataFiRealitzacio >='"+avui+"' "                
                + "AND P.estat<> '"  +EstatProva.TANCADA.getEstat() +"' "
                + "AND P.estat<>'"  +EstatProva.CANCELADA.getEstat() +"' ";
                                
        return getProves(sql);
    }
    /**
     * Accessor de lectura, recupera totes les proves en estat TANCADA
     * @return LLista de proves
     * @throws EOlympicsException 
     */
    public List<Prova> getProvesTancades() throws EOlympicsException, EOlympicsExceptionProva{                
        String sql="SELECT P.idProva,P.descripcio,P.dataIniInscripcio,P.dataFiInscripcio,P.nombrePlaces "
                + "FROM PROVA P "                
                + "WHERE P.estat = '"  +EstatProva.TANCADA.getEstat() +"'";
        return getProves(sql);
    }
    /**
     * Accessor de Lectura,recupera totes les proves en estat CANCELADA
     * @return LLista de proves
     * @throws EOlympicsException 
     */
    public List<Prova> getProvesCancelades() throws EOlympicsException, EOlympicsExceptionProva{                
        String sql="SELECT P.idProva,P.descripcio,P.dataIniInscripcio,P.dataFiInscripcio,P.nombrePlaces "
                + "FROM PROVA P "                
                + "WHERE P.estat = '"  +EstatProva.CANCELADA.getEstat() +"'";
        return getProves(sql);
    }
    /**
     * Recupera una llista de proves
     * @param sql                       Setència SQL per recuperar les proves
     * @return  Una llista deproves
     * @throws EOlympicsException 
     */
    public List<Prova> getProves(String descripcio,Date IniInscripcio, Date fiInscripcio, Date iniRealitzacio, Date fiRealitzacio) throws  EOlympicsExceptionProva, EOlympicsException{
        List <Prova>proves= new ArrayList<Prova>();
        Prova prova=null;
        Statement st=gestor.creaSentencia();

         String sql="SELECT DISTINCT p.idProva, p.descripcio, p.dataIniInscripcio,p.datafiInscripcio,p.estat,"
                +         "p.nombrePlaces,p.dataAlta,p.dataMod,p.dataBaixa "
                + "FROM prova p ,ronda r WHERE p.idprova=r.idprova and p.descripcio LIKE '"+EOlympicsUtils.validarApostrof(descripcio)+"%' "
                + "AND (p.datainiinscripcio between '"+new java.sql.Date(IniInscripcio.getTime())+"' AND '"+ new java.sql.Date(fiInscripcio.getTime())+"') "
                + "AND (p.datafiinscripcio between '"+new java.sql.Date(IniInscripcio.getTime())+"' AND '"+ new java.sql.Date(fiInscripcio.getTime())+"') "
                + "AND (r.datainiciRealitzacio between '"+new java.sql.Date(iniRealitzacio.getTime())+"' AND '"+ new java.sql.Date(fiRealitzacio.getTime())+"') "
                + "AND (r.datafiRealitzacio between '"+new java.sql.Date(iniRealitzacio.getTime())+"' AND '"+ new java.sql.Date(fiRealitzacio.getTime())+"') "
                 + "order by idProva";
         
        
        try{
            ResultSet rs=st.executeQuery(sql);
            while (rs.next()){                                
                prova=new Prova(rs.getInt(1),rs.getString(2));
                prova.setDataIniInscripcio(rs.getDate(3));
                prova.setDataFiInscripcio(rs.getDate(4));   
                if(!rs.getString(5).equals ("")) {                     
                    if(rs.getString(5).equals(EstatProva.INICIAL.getEstat())&& rs.getDate(3).before(new java.sql.Date(System.currentTimeMillis()))) {
                        prova.setEstat(EstatProva.INSCRIPCIO);
                    }else {
                        prova.setEstat(EstatProva.valueOf(rs.getString(5)));
                    }
                    
                      
                }                    
                else{
                    prova.setEstat(EstatProva.INICIAL);
                }
                prova.setNombrePlaces(rs.getInt(6));
                prova.setDataCreacio(rs.getDate(7));
                prova.setDataModificacio(rs.getDate(8));
                prova.setDataEsborrat(rs.getDate(9));                
                proves.add(prova);
            }
            st.close();
            rs.close();
        }catch (SQLException sqle){
            System.out.println(sqle.getMessage());
            treatExceptionSQL(sqle.getMessage());
            
        }catch (Exception e){
            System.out.println(e.getMessage());
            throw new EOlympicsException(EOlympicsException.ERR_DESC_EXEC);
        }                        
        return proves;
        
    }
    
    
    /**
     * Obté un llistat de proves 
     * @param sql           Cadena Sql 
     * @return  LListat de proves
     * @throws EOlympicsException
     * @throws EOlympicsExceptionProva 
     */
    private List<Prova> getProves(String sql) throws EOlympicsException, EOlympicsExceptionProva{
        List <Prova>proves= new ArrayList<Prova>();
        Statement st=gestor.creaSentencia();
        
        try{
            ResultSet rs=st.executeQuery(sql);
            while (rs.next()){                                
                
                proves.add(new Prova(rs.getInt(1),rs.getString(2),rs.getDate(3),rs.getDate(4),rs.getInt(5)));
            }
            st.close();
            rs.close();
        }catch (SQLException sqle){
            treatExceptionSQL(sqle.getMessage());
            
        }catch (Exception e){
            System.out.println(e.getMessage());
            throw new EOlympicsException(EOlympicsException.ERR_DESC_EXEC);
        }                        
        return proves;
        
    }
    
    /**
     * Accessor de lectura, recupera una prova a partir del seu identificador.
     * @param idProva               Identificador de la prova.
     * @return  Prova
     * @throws EOlympicsException 
     */
    public Prova getProva(Integer idProva) throws EOlympicsException{
        Prova prova = null;
        GestorRonda gRonda= new GestorRonda(gestor);
        Statement st=gestor.creaSentencia();
        
        String sql="SELECT P.idProva,P.descripcio,p.dataIniInscripcio,P.dataFiInscripcio,P.nombrePlaces, P.estat,"
                + "P.dataAlta,P.dataBaixa,P.dataMod "
                + "FROM PROVA P "                
                + "WHERE P.idProva="+ idProva ;
        try{
            ResultSet rs=st.executeQuery(sql);
            if (rs.next()){                                
                if(rs.getString(6).equals("")){
                  prova=(new Prova(rs.getInt(1),rs.getString(2),rs.getDate(3),rs.getDate(4),rs.getInt(5),EstatProva.INICIAL));
                }else{              
                    prova=(new Prova(rs.getInt(1),rs.getString(2),rs.getDate(3),rs.getDate(4),rs.getInt(5),EstatProva.valueOf(rs.getString(6))));
                }
              
                if(prova.getEstat().equals(EstatProva.INICIAL.getEstat())&& prova.getDataIniInscripcio().before(new java.sql.Date(System.currentTimeMillis()))){
                    prova.setEstat(EstatProva.INSCRIPCIO);                    
                }
                
                prova.setDataCreacio(rs.getDate(7));
                prova.setDataEsborrat(rs.getDate(8));
                prova.setDataModificacio(rs.getDate(9));
                prova.setRondaEliminatoria(gRonda.getRondaEliminatoria(idProva));        
                prova.setRondaFinal((RondaFinal)gRonda.getRondaFinal(idProva));    
            }
            st.close();
            rs.close();
        }catch (SQLException sqle){
            System.out.println(sqle.getMessage());
            treatExceptionSQL(sqle.getMessage());
        }catch (Exception e){
            System.out.println(e.getMessage());
            throw new EOlympicsException(EOlympicsException.ERR_DESC_EXEC);
        }
        
        return prova;
    }
    
    /**
     * Accessor d'escriptura, Insereix una nova proba a la BBDD.
     * @param prova                 Prova a inserir.
     * @return idProva              Identificador de la prova inserida. 
     * @throws EOlympicsException 
     */
    private Integer setAltaProva(Prova prova) throws EOlympicsException{
        GestorRonda gRonda=new GestorRonda(gestor);
        
        Integer idProva=0;
        Statement st=gestor.creaSentencia();
        
        
        String sql="INSERT INTO PROVA "
                + "(descripcio,dataIniInscripcio,dataFiInscripcio,nombrePlaces,estat,dataAlta,usuariAlta) "
                + "VALUES('"+EOlympicsUtils.validarApostrof(prova.getDescripcio()) + "','"
                + new java.sql.Date(prova.getDataIniInscripcio().getTime())+ "','"
                + new java.sql.Date(prova.getDataFiInscripcio().getTime())+ "',"
                + prova.getNombrePlaces()+ ",'"
                + prova.getEstat()+"','"
                + new Date(System.currentTimeMillis())+ "',"
                + prova.getUsuariCreacio().getIdIntern()+") "                
                + "RETURNING idProva";
               
       try{
           gestor.getConnexio().setAutoCommit(false);
           ResultSet rs=st.executeQuery(sql); 
           if(rs.next()){
                idProva=rs.getInt(1);
                RondaEliminatoria ronda=prova.getRondaEliminatoria();
                if(ronda != null) {
                    gRonda.guardarRonda(idProva, "E",ronda);
                }        
                
                RondaFinal rondaf=prova.getRondaFinal();
                if(rondaf != null){
                    gRonda.guardarRonda(idProva, "F",rondaf);
                }
           }
                     
           gestor.getConnexio().commit();
           rs.close();   
       }catch(SQLException sqle){
           System.out.println(sqle.getMessage());
            try {
                gestor.getConnexio().rollback();
                treatExceptionSQL(sqle.getMessage());
            } catch (SQLException ex) {
                treatExceptionSQL(ex.getMessage());
            }
           treatExceptionSQL(sqle.getMessage());                                       
       }        
        return idProva;
    }
    
    /**
     * Acessor d'escriptura, modifica les dades d'una prova
     * @param prova                 prova que cal modificar
     * @return operacions           Nombre de proves modificades 
     * @throws EOlympicsException 
     */
    private int setModificarProva(Prova prova) throws EOlympicsException, EOlympicsExceptionProva{
        GestorRonda gRonda=new GestorRonda(gestor);
        Integer operacions=0;
        Integer idProva=prova.getIdProva();
        Statement st=gestor.creaSentencia();
        String sql="UPDATE PROVA "
                + "SET descripcio=?,dataIniInscripcio=?,dataFiInscripcio=?,nombrePlaces=?,estat=?,dataMod=?,usuariMod=? "
                + "WHERE idProva=?";
       PreparedStatement ps = gestor.crearPreparedStatement(sql);
       
       try{
           ps.setString(1, prova.getDescripcio());
       
           ps.setDate(2, new java.sql.Date(prova.getDataIniInscripcio().getTime()));
           ps.setDate(3, new java.sql.Date(prova.getDataFiInscripcio().getTime()));
           
           ps.setInt(4, prova.getNombrePlaces());
           ps.setString(5, prova.getEstat());           
           ps.setDate(6, new java.sql.Date(System.currentTimeMillis()));           
           ps.setInt(7, prova.getUsuariModificacio().getIdIntern());
           ps.setInt(8, prova.getIdProva());
           gestor.getConnexio().setAutoCommit(false);
           operacions=ps.executeUpdate();
           
           if(operacions==0){
               throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL);
           }else{
               
                RondaEliminatoria ronda=prova.getRondaEliminatoria();
                if(ronda != null) {
                    gRonda.guardarRonda(prova.getIdProva(), "E",ronda);
                }        
                RondaFinal rondaf=prova.getRondaFinal();
                if(rondaf != null){
                    gRonda.guardarRonda(prova.getIdProva(), "F",rondaf);
                }
           }
           gestor.getConnexio().commit();
           ps.close();
       }catch(SQLException sqle){
           try {
                gestor.getConnexio().rollback();
                ps.close();
                treatExceptionSQL(sqle.getMessage());
            } catch (SQLException ex) {
                treatExceptionSQL(ex.getMessage());
            }            
       }catch(EOlympicsException eor){
           try {
                gestor.getConnexio().rollback();
                ps.close();
                treatExceptionSQL(eor.getMessage());
            } catch (SQLException ex) {
                treatExceptionSQL(ex.getMessage());
            }
       }
        return idProva;
    }
    /**
     * Cancela una prova
     * @param prova             Prova a cancelar
     * @return  Numero d'operacions realitzades en el SGBD                
     * @throws EOlympicsException
     * @throws EOlympicsExceptionProva 
     */
    public int setCancelarProva(Prova prova) throws EOlympicsException, EOlympicsExceptionProva{
        GestorRonda gRonda=new GestorRonda(gestor);
        Integer operacions=0;
        Integer idProva=prova.getIdProva();
        Statement st=gestor.creaSentencia();
        prova.setEstat(EstatProva.CANCELADA);
        String sql="UPDATE PROVA "
                + "SET estat=?,dataBaixa=?,usuariBaixa=? "
                + "WHERE idProva=?";
       PreparedStatement ps = gestor.crearPreparedStatement(sql);
       
       try{           
           ps.setString(1, prova.getEstat());
           ps.setDate(2, new java.sql.Date(System.currentTimeMillis()));
           ps.setInt(3, prova.getUsuariEsborrat().getIdIntern());
           ps.setInt(4, prova.getIdProva());
           gestor.getConnexio().setAutoCommit(false);
           operacions=ps.executeUpdate();
           
           if(operacions==0){
               throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL);
           }else{
               
                RondaEliminatoria ronda=prova.getRondaEliminatoria();
                if(ronda != null) gRonda.setCancelacioRonda(prova.getIdProva(), "E",ronda);        
                RondaFinal rondaf=prova.getRondaFinal();
                if(ronda != null)gRonda.setCancelacioRonda(prova.getIdProva(), "F",rondaf);
           }
           gestor.getConnexio().commit();
           ps.close();
       }catch(SQLException sqle){
           try {
                gestor.getConnexio().rollback();
                treatExceptionSQL(sqle.getMessage());
            } catch (SQLException ex) {
                treatExceptionSQL(ex.getMessage());
            }            
       }
        return idProva;
    }
    /**
     * Guarda una prova
     * @param prova             Prova a guardar
     * @return  Número d'operacions realitzades en el SGBD
     * @throws EOlympicsException 
     */
    public int guardarProva(Prova prova) throws EOlympicsException{
        Integer idProva;
        if(!existeixProva(prova.getIdProva())){
            idProva=setAltaProva(prova);
        } 
        else
        {
            idProva=setModificarProva(prova);
        }
        return idProva;
    }
    /**
     * Comprova si una prova existeix en el sistema
     * @param idProva               identificador de la prova
     * @return  cert si existeix, fals en cas contrari
     * @throws EOlympicsException
     * @throws EOlympicsExceptionProva 
     */
    private boolean existeixProva(Integer idProva)throws  EOlympicsException, EOlympicsExceptionProva{
        boolean existeix=false;
        Statement st=gestor.creaSentencia();
        String sql="SELECT P.idProva "
                + "FROM PROVA P "                
                + "WHERE P.idProva="+ idProva ;        
        
        try {
        ResultSet rs = st.executeQuery(sql);
            if (rs.next())existeix=true;
            st.close();
            rs.close();
        } catch (SQLException ex) {
            treatExceptionSQL(ex.getMessage());
        }
            
            return existeix;
    }
    /**
     * Tanca la inscripció d'una prova
     * @param prova                     Prova a tancar la inscripció
     * @throws EOlympicsException
     * @throws EOlympicsExceptionProva 
     */
    public void tancarInscripcio(Prova prova) throws EOlympicsException,EOlympicsExceptionProva{
        
        Statement st=gestor.creaSentencia();
        List<Participacio> participacions = new ArrayList<Participacio>();
        
        String sql="UPDATE PROVA SET estat='"+prova.getEstat()+"',usuariMod="+prova.getUsuariModificacio().getIdIntern() +", "
                + "dataMod='"+ new java.sql.Date(System.currentTimeMillis()) +"' "
                + "WHERE idProva ="+ prova.getIdProva() ;
        
        try {
            if(prova.getEstat().equals(EstatProva.COMPETICIOPREVIA.getEstat())){
                //cal buscar els inscrits i anotar-los a participacio amb la ronda eliminatoria
                participacions=getInscrits(prova,"E");                
            }                
            else if (prova.getEstat().equals(EstatProva.COMPETICIOFINAL.getEstat())){
                //cal buscar els inscrits i anotar-los a participacio amb ronda final
                participacions=getInscrits(prova,"F");
            }     
            
            gestor.getConnexio().setAutoCommit(false);
            st.executeUpdate(sql);
            if(!prova.getEstat().equals(EstatProva.DESERTA.getEstat())){
                setAltaParticipacio(participacions);
            }
            
            gestor.getConnexio().commit();
            st.close();
        } catch (SQLException sqle) {
            try {
                gestor.getConnexio().rollback();
                if (!st.isClosed()) st.close(); 
                treatExceptionSQL(sqle.getMessage());
            } catch (SQLException ex) {                
                treatExceptionSQL(ex.getMessage());
            }            
        }catch (EOlympicsException eoe){
            treatExceptionSQL(eoe.getMessage());
        }
        
    }
    /**
     * Obté les inscripcions d'una prova
     * @param prova                 Prova 
     * @param tipusRonda            Tipus de ronda
     * @return Llistat de participacions
     * @throws SQLException 
     */
    private List<Participacio> getInscrits (Prova prova, String tipusRonda) throws SQLException{
        List <Participacio> participacions = new ArrayList<Participacio>();
        Participacio participacio;
        Estudiant estudiant;
        String sql= "Select idEstudiant FROM inscripcio WHERE idProva=" + prova.getIdProva();
        Statement st= gestor.creaSentencia();
        ResultSet rs= st.executeQuery(sql);
        while(rs.next()){
           participacio=new Participacio(); estudiant=new Estudiant();
           estudiant.setIdIntern(rs.getInt(1));           
           participacio.setEstudiant(estudiant);
           participacio.setTipusRonda(tipusRonda);
           participacio.setProva(prova);
           participacions.add(participacio);           
        }                
        return participacions;
    }
    /**
     * Guarda una llista de participacions
     * @param participacions            llista de partipacions
     * @throws EOlympicsException
     * @throws SQLException 
     */
    private void setAltaParticipacio(List<Participacio> participacions) throws EOlympicsException, SQLException{
        PreparedStatement ps;
        String sql="INSERT INTO PARTICIPACIO "
                + "VALUES (?,?,?,?,?,?,?,?)";                
        ps =gestor.crearPreparedStatement(sql);
        for(Participacio participacio:participacions){
            ps.setInt(1, participacio.getProva().getIdProva());
            ps.setString(2,participacio.getTipusRonda());
            ps.setInt(3, participacio.getEstudiant().getIdIntern());
            ps.setDate(4, new java.sql.Date(System.currentTimeMillis()));
            ps.setInt(5, 0);
            ps.setInt(6, 0);
            ps.setInt(7, 0);
            ps.setInt(8, 0);
            ps.executeUpdate();
        }
    }
    /**
     * Guarda una llista de participacions
     * @param prova                     prova a guardar
     * @param tipusRonda                Tipus de ronda a guardar
     * @throws EOlympicsExceptionProva
     * @throws EOlympicsException 
     */
    public void inscriureParticipantsAFinal(Prova prova, String tipusRonda) throws EOlympicsExceptionProva, EOlympicsException {                
        try {
            //primer aconseguir els 10 millors
            // inscriure'ls a l final. 
            gestor.getConnexio().setAutoCommit(false);           
            setAltaParticipacio(getParticipacioEliminatoria(prova));
            gestor.getConnexio().commit();
        } catch (SQLException ex) {
            try {
                treatExceptionSQL(ex.getMessage());
                gestor.getConnexio().rollback();
            } catch (SQLException ex1) {
                treatExceptionSQL(ex1.getMessage());
            }
        }        
    }
    /**
     * Obté la participació d'una Ronda eliminatoria
     * @param prova             Prova que cal recuperar
     * @return  Llistat de participacions
     * @throws SQLException 
     */
    private List<Participacio> getParticipacioEliminatoria(Prova prova) throws SQLException{
        Statement st;
        Estudiant estudiant;
        Participacio participacio;
        List<Participacio> participacions=new ArrayList<Participacio>();

        String sql= "SELECT idEstudiant FROM PARTICIPACIO P "
                + "WHERE idProva="+ prova.getIdProva()
                + " AND tipusRonda='E' "
                + "AND (Select count(*) From respostaEstudiant where idprova="+prova.getIdProva()+ " AND tipusRonda='E' "
                + "AND idEstudiant = P.idEstudiant)>0 "
                + "ORDER BY nota desc, dataParticipacio LIMIT 10";
        
        
        
        st=gestor.creaSentencia();
        ResultSet rs=st.executeQuery(sql);        
        while(rs.next()){
            estudiant = new Estudiant();
            estudiant.setIdIntern(rs.getInt(1));
            participacio=new Participacio();
            participacio.setProva(prova);
            participacio.setTipusRonda("F");
            participacio.setEstudiant(estudiant);
            participacions.add(participacio);            
        }
        return participacions;
    }
    /**
     * Tracta les excepcions SQL, diferenciant-les pel missatge de l'error
     * @param sqle                      ERROR.message()
     * @throws EOlympicsExceptionProva
     * @throws EOlympicsException 
     */
    private void treatExceptionSQL(String sqle) throws EOlympicsExceptionProva, EOlympicsException{           
         System.out.println("prova: "+ sqle);
            if(sqle.contains("pk_prova")) {
               throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_PK_PROVA);
           }else if(sqle.contains("ck_datainsc")) {
               throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_CK_PROVA);           
           }
           else{
              
                if(sqle.contains("pk_respostacorrecta")) {
                    throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_PK_RONDA_PREGUNTA);
                }else if(sqle.contains("fk_ronda_rc")) {               
                    throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_FK_RONDA_RC);
                }else if(sqle.contains("fk_usuari_alta_rc")) {               
                    throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_FK_USUARI_RONDA);
                }else if(sqle.contains("pk_Ronda")) {
                    throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_PK_RONDA);
                }else if(sqle.contains("fk_prova_rond")) {               
                    throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_FK_PROVA_RONDA);
                }else if(sqle.contains("fk_usuari_alta_ronda")) {               
                    throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_FK_USUARI_RONDA);
                }else if(sqle.contains("ck_datainsc")) {
                    throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_CK_DATA_RONDA);
                }else if(sqle.contains("pk_participacio")) {
                    throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_PK_PARTICIPACIO);
                }else if(sqle.contains("fk_inscripcio_part")) {
                    throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_FK_INSCRIPCIO);
                }else if(sqle.contains("fk_ronda_part")) {
                    throw new EOlympicsExceptionProva(EOlympicsExceptionProva.ERR_SQL_FK_RONDA);
                }                              
                else{
                    
                throw new EOlympicsException(EOlympicsException.ERR_SQL);
               }
        
         }
           
        
    }
    
    
    
    
}
